<script setup lang="ts">
import { onDeactivated, ref } from 'vue';
import Renderer from '@/soar/components/LgFlowChat/Renderer.vue';
import type { Node, Task } from '@/soar/components/LgFlowChat/type';
import ApprovalPanel from './panels/ApprovalPanel.vue';
import StartPanel from './panels/StartPanel.vue';
import ConditionPanel from './panels/ConditionPanel.vue';
import EndPanel from './panels/EndPanel.vue';
import CcPanel from './panels/CcPanel.vue';
import NotifyPanel from './panels/NotifyPanel.vue';
import TimerPanel from './panels/TimerPanel.vue';
import ServicePanel from './panels/ServicePanel.vue';
import FlowPanel from './panels/FlowPanel.vue';

const props = defineProps<{
  data: any;
}>();

const startRef = ref();
const approvalRef = ref();
const carbonCopyRef = ref();
const notifyRef = ref();
const timerRef = ref();
const serviceRef = ref();
const conditionRef = ref();
const endRef = ref();
const flowRef = ref();
const key = ref();

function click(d: Node) {
  switch (d.type) {
    case 'start':
      startRef.value.open(d, props.data);
      break;
    case 'approval':
      approvalRef.value.open(d, props.data);
      break;
    case 'carbon-copy':
      carbonCopyRef.value.open(d, props.data);
      break;
    case 'notify':
      notifyRef.value.open(d, props.data);
      break;
    case 'timer':
      timerRef.value.open(d, props.data);
      break;
    case 'service':
      serviceRef.value.open(d, props.data);
      break;
    case 'end':
      endRef.value.open(d, props.data);
      break;
    default:
      conditionRef.value.open(d, props.data);
      break;
  }
}

function find(list: Node[], key: string) {
  for (let i = 0; i < list.length; i++) {
    const x = list[i];
    if (x.key === key) {
      return { list, data: x, index: i };
    }
    if (x.type === 'exclusive-gateway') {
      for (let j = 0; j < x.items.length; j++) {
        const item = x.items[j];
        if (item.key === key) {
          return {
            gateway: x,
            list: x.items,
            data: item,
            index: j,
          };
        }
        const res = find(item.nodes, key);
        if (res) {
          res.gateway = x;
          res.gatewayItem = item;
          return res;
        }
      }
    }
  }
}

const actionStyle = ref();

let addInfo: any = null;
function add(node: Node) {
  if (addInfo.gateway && !addInfo.data.type) {
    addInfo.data.nodes.splice(0, 0, node);
  } else {
    addInfo.list.splice(addInfo.index + 1, 0, node);
  }
  actionStyle.value = null;
  key.value = Math.random().toString(36);
}
const p = new Date().getTime().toString(36);
const ids = {
  approval: 1,
  carbonCopy: 1,
  notify: 1,
  timer: 1,
  service: 1,
  gateway: 1,
  gatewayItem: 1,
};
function addApproval() {
  add({
    type: 'approval',
    key: `UT_${p}_${ids.approval}`,
    name: `审批人_${p}_${ids.approval++}`,
    description: '',
    instanceType: 0,
    missingAssignee: 0,
    backType: 0,
    assignees: [{ type: 10 }],
    fieldPermits: [],
    buttons: [
      { key: 'pass', name: '通过' },
      { key: 'reject', name: '驳回' },
    ],
    nodeListeners: [],
    processListeners: [],
  });
}

function addCarbonCopy() {
  add({
    type: 'carbon-copy',
    key: `CC_${p}_${ids.carbonCopy}`,
    name: `抄送_${p}_${ids.carbonCopy++}`,
    description: '',
    processListeners: [],
  });
}

function addNotify() {
  add({
    type: 'notify',
    key: `N_${p}_${ids.notify}`,
    name: `通知_${p}_${ids.notify++}`,
    description: '',
    processListeners: [],
  });
}

function addTimer() {
  add({
    type: 'timer',
    key: `T_${p}_${ids.timer}`,
    name: `计时器_${p}_${ids.timer++}`,
    description: '',
    processListeners: [],
  });
}

function addService() {
  add({
    type: 'service',
    key: `S_${p}_${ids.service}`,
    name: `服务节点_${p}_${ids.service++}`,
    description: '',
    processListeners: [],
  });
}

function addExclusive() {
  add({
    type: 'exclusive-gateway',
    key: `EG_${p}_${ids.gateway}`,
    name: `排他网关_${p}_${ids.gateway++}`,
    items: [
      {
        name: '默认条件',
        key: `EI_${p}_${ids.gatewayItem++}`,
        nodes: [],
        processListeners: [],
        isDefault: true,
        description: '默认条件',
      },
      { name: '未设置条件', key: `EI_${p}_${ids.gatewayItem++}`, nodes: [] },
    ],
  });
}

function addNode(e: any) {
  const res = find(props.data.nodes, e.data.key);
  if (res) {
    // 获取鼠标点击在视口中的坐标
    const target: any = e.$event.target.getBoundingClientRect();
    const rect = document.querySelector('.lg-flowchart-designer').getBoundingClientRect();
    const clickY = target.top + target.height / 2;
    const clickX = target.left + target.width / 2;
    const top = clickY - rect.top;
    const left = clickX - rect.left;
    const style: any = { top: `${top}px` };
    if (rect.width - left < 350) {
      // 显示在左侧
      style.right = `${rect.width - clickX + 32}px`;
    } else {
      // 显示在右侧
      style.left = `${left + 32}px`;
    }
    if (rect.height - top < 300) {
      style.transform = `translateY(-100%)`;
    }
    actionStyle.value = style;
    addInfo = res;
  }
}

function delNode(d: any) {
  const res = find(props.data.nodes, d.key);
  if (res) {
    res.list.splice(res.index, 1);
    if (res.list.length === 0 && res.gateway) {
    }
  }
  key.value = Math.random().toString(36);
}

function addCondition(d: any) {
  d.items.push({ name: '未设置条件', key: `EI_${p}_${ids.gatewayItem++}`, nodes: [] });
  key.value = Math.random().toString(36);
}

function delCondition(res: any) {
  res.gateway.items.splice(res.index, 1);
  if (res.gateway.items.length < 2) {
    delNode(res.gateway);
  }
  key.value = Math.random().toString(36);
}

function hideAction() {
  actionStyle.value = null;
}
onDeactivated(() => {
  window.removeEventListener('click', hideAction);
  window.removeEventListener('contextmenu', hideAction);
});
window.addEventListener('click', hideAction);
window.addEventListener('contextmenu', hideAction);
</script>

<template>
  <div class="lg-flowchart-designer">
    <t-button style="position: absolute; z-index: 9" @click="flowRef.open(data)">流程配置</t-button>
    <renderer
      :key="key"
      :data="data.nodes"
      style="height: 100%"
      @click="click"
      @add-node="addNode"
      @del-node="delNode"
      @add-condition="addCondition"
      @del-condition="delCondition"
    />
    <div v-if="actionStyle" class="lg-f-action" :style="actionStyle">
      <div @click="addApproval">审批人</div>
      <div @click="addCarbonCopy">抄送人</div>
      <div @click="addExclusive">互斥网关</div>
      <div @click="addNotify">消息通知</div>
      <div @click="addTimer">计时等待</div>
      <div @click="addService">服务任务</div>
    </div>
  </div>
  <start-panel ref="startRef" />
  <approval-panel ref="approvalRef" />
  <cc-panel ref="carbonCopyRef" />
  <notify-panel ref="notifyRef" />
  <timer-panel ref="timerRef" />
  <service-panel ref="serviceRef" />
  <condition-panel ref="conditionRef" />
  <end-panel ref="endRef" />
  <flow-panel ref="flowRef" />
</template>

<style scoped lang="less">
.lg-flowchart-designer {
  height: 100%;
  position: relative;
  .lg-f-action {
    position: absolute;
    display: flex;
    flex-wrap: wrap;
    width: 322px;
    padding: 8px;
    background: var(--app-color-bg-primary);
    border-radius: 10px;
    box-shadow: var(--app-box-shadow);
    :nth-child(n) {
      border: 1px solid #ddd;
      border-radius: 10px;
      margin: 4px;
      cursor: pointer;
      display: flex;
      padding: 8px;
      width: 135px;
      position: relative;
      background-color: var(--app-color-bg-secondary);
      &:hover {
        background-color: var(--el-color-primary-light-9);
        box-shadow: var(--el-box-shadow-light);
        color: var(--el-color-primary);
      }
    }
  }
}
</style>
